Math Sci Life Code Log in

Codes

Code your ideas for understanding of natural systems

Updated at 2021.6.7

Dependency Injection

Dependency Injection는 종속성 주입 또는 의존성 주입이라고 하는데, 클래스를 설계할 때 두 개 이상의 클래스 사이의 관계를 설정하는 방법이다.

클래스 관계 설정

프로그래밍에서 많이 맞딱들이는 상황이 어떤 클래스에서 다른 클래스를 사용하고자 할 때 어떻게 할 것인가 이다.

예를 들어 아래와 같이 ClassB에서 ClassA를 초기화하여 사용하면 ClassA를 변경하고자 할 때 코드를 직접 수정하지 않으면 안된다.

class ClassA {
  public string Name { get; set;}
  
  public void SetAndPrintOut(string firstName, string familyName)
  {
    Name = $"{firstName}, {familyName}";
    Console.WriteLine(Name);
  }
}

class ClassB {
  private ClassA _classA = new();

  public void PrintOut(string firstName)
  {
    _classA.SetAndPrintOut(firstName, "Kim");
  }
}

더구나 아래의 다이어그램과 같이 ClassA와 유사한 클래스(ClassAA 등)나 객체가 많아서 그것을 ClassB에서 사용하고자 한다면 어떻게 하면 될까?

graph LR subgraph ClassB ClassA ClassAA end

인터페이스와 종속성 주입

아래의 다이어그램과 같은 방식으로 종속성 주입을 활용하면 이러한 문제를 해결할 수 있다.

graph LR subgraph ClassB IClassA end IClassA -.-> ClassA IClassA -.-> ClassAA

위의 코드를 아래와 같이 수정하면 ClassA가 변경되어도 ClassB를 다시 코딩할 필요가 없다. 즉 느슨하게 결합 (Loosely Coupled)된 코딩을 할 수 있다.

  • 인터페이스(Interface) IClassA 선언
  • 인터페이스를 상속받는 ClassA 선언
  • ClassB에서 IClass를 내부 필드(Field)로 선언하고, 생성자에서 변수를 입력 받아서 대입
interface IClassA {
  string Name { get; set;}
  void SetAndPrintOut(string firstName, string familyName);
}

class ClassA: IClassA {
  public string Name { get; set;}
  
  public void SetAndPrintOut(string firstName, string familyName)
  {
    Name = $"{firstName}, {familyName}";
    Console.WriteLine(Name);
  }
}

class ClassB {
  private readonly IClassA _classA;

  public ClassB(IClassA classA)
  {
    _classA = classA;
  }

  public void PrintOut(string firstName)
  {
    _classA.SetAndPrintOut(firstName, "Kim");
  }
}

ASP.NET에서의 종속성 주입이란?

웹코딩에서 글로벌 변수로 선언하여 모든 하위 웹에서 그 객체를 공용으로 사용하고 싶을 때 어떻게 할 것인가? ASP.NET에서는 Startup 클래스의 ConfigureServices 함수내에서 IServiceCollection의 사용할 수 있는 다음과 같은 3가지 함수를 제공한다.

graph TD A(IServiceCollection) --> AddTransient A --> AddScoped A --> AddSingleton

서비스 수명에 따라 선택해서 사용하면 된다. Server를 기준으로 간단히 정리해 보면 다음과 같다.

수명 설명
Transient 요청할 때마다
Scoped 새 창을 열고 다시 접속할 때마다 또는 새로 고침할 때마다
Singletone 처음 시작할 때만

실제 코딩에서의 사용법은 다음과 같다.

public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddSingleton<ClassA>();
    services.AddSingleton<IClassA, ClassA>();
  }
}

파라미터를 가지고 종속성 주입하기

ClassA의 생성자가 파라미터를 가지고 있는 경우, 그리고 그 파라미터도 서비스로 등록이 되어 있는 경우에는 어떻게 할 것인가? 즉 글로벌 객체를 인자로 가지는 글로벌 객체를 선언해야 할 경우이다.

public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddSingleton<IClassA, ClassA>();
    services.AddSingleton(x => new ClassB(x.GetService<IClassA, ClassA>()));
  }
}

17 개의 글이 있습니다.

# 제목 날짜 조회수
01 CS 배우기 요약 2021/06/07 145
02 CS Statements 2021/06/07 128
03 퍼셉트론 2021/04/15 125
04 Blazor and Sqlite 2021/04/15 137
05 Blazor Layouts 2021/04/15 161
06 CS Language Reference 2021/06/07 127
07 VSCode and Markdown 2021/04/15 138
08 Blazor에서 이미지파일 다루기 2021/06/10 211
09 Blazor and Markdown 2021/04/15 145
10 종속성 주입 2021/06/07 153
11 Blazor에서 데이터 다루기 2021/06/07 137
12 Blazor Components 2021/04/15 148
13 CS Glossary 2021/06/07 126
14 Enum 타입 다루기 2021/12/14 135
15 생활코딩 CS01 2022/04/25 261
16 생활코딩 CS02 2022/04/30 165
17 생활코딩 CS03 2022/04/30 441

Most Popular #3

Recent #3

An error has occurred. This application may no longer respond until reloaded. Reload 🗙